package com.bwda.dsrs.filecenter.ftpsdk.impl;

import com.bwda.dsrs.filecenter.domain.BusinessConstants;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @description:
 * @author: yangjun
 * @create: 2019-07-16 16:03
 */
public final class FtpServcieImpl extends AbstractFtpService {
    private final Logger logger = LoggerFactory.getLogger(FtpServcieImpl.class);
    private FTPClient ftpClient = null;

    private FtpServcieImpl() {
    }

    public static FtpServcieImpl getInstance() {
        return new FtpServcieImpl();
    }

    @Override
    protected boolean connection() {
        if (this.ftpClient != null) {
            return true;
        } else if (!this.inited) {
            return false;
        } else {
            boolean result = false;
            this.ftpClient = new FTPClient();
            if (this.timeout > 0) {
                this.ftpClient.setConnectTimeout(this.timeout);
            }

            this.ftpClient.setControlEncoding(this.controlEncoding);

            try {
                this.ftpClient.connect(this.ip, this.port);
                if (!FTPReply.isPositiveCompletion(this.ftpClient.getReplyCode())) {
                    this.ftpClient = null;
                    this.logger.info("FTP Server:{},Port{},MSG:{}", new Object[]{this.ip, String.valueOf(this.port), "服务器拒绝建立连接！"});
                } else {
                    result = this.ftpClient.login(this.username, this.password);
                    if (!result) {
                        this.ftpClient = null;
                        this.logger.info("FTP Server:{},Port{},MSG:{}", new Object[]{this.ip, String.valueOf(this.port), "检查用户名/密码是否正确"});
                    } else {
                        this.logger.info("FTP Server:{},Port{},MSG:{}", new Object[]{this.ip, String.valueOf(this.port), "FTP登陆成功"});
                        this.ftpClient.setFileTransferMode(10);
                        this.ftpClient.setFileType(2);
                        if (this.enterMode == BusinessConstants.TWO_INT) {
                            this.ftpClient.enterLocalActiveMode();
                        } else {
                            this.ftpClient.enterLocalPassiveMode();
                        }
                    }
                }
            } catch (Exception var3) {
                this.ftpClient = null;
                this.logger.error("{}", var3.toString());
            }

            return result;
        }
    }

    @Override
    protected void disConnection() {
        if (this.ftpClient != null) {
            try {
                this.ftpClient.disconnect();
            } catch (Exception var5) {
                this.logger.error("{}", var5.toString());
            } finally {
                this.logger.info("FTP Server:{},用户{}已退出！");
                this.ftpClient = null;
            }

        }
    }

    @Override
    protected boolean uploadFileSub(String strLocalFile, String strRemotePath) {
        boolean result = false;
        String strRemoteFile = this.getFileName(strLocalFile);
        FileInputStream inputStream = null;

        boolean var8;
        try {
            inputStream = new FileInputStream(strLocalFile);
            if (this.ftpClient != null) {
                result = this.ftpClient.storeFile(strRemoteFile, inputStream);
                inputStream.close();
                this.logger.info("工作目录:{},上传文件成功：{}", this.workingDirectory, strRemoteFile);
            }

            return result;
        } catch (Exception var11) {
            this.logger.error("{}", var11.toString());
            var8 = result;
        } finally {
            inputStream = null;
        }

        return var8;
    }

    @Override
    protected boolean downloadFileSub(String strRemoteFile, String strLocalFile) {
        boolean result = false;
        File fileOut = new File(strLocalFile);
        FileOutputStream outputStream = null;

        try {
            outputStream = new FileOutputStream(fileOut);
            if (this.ftpClient != null) {
                this.ftpClient.retrieveFile(strRemoteFile, outputStream);
                outputStream.close();
                result = true;
                this.logger.info("工作目录:{},下载文件成功：{}", this.workingDirectory, strRemoteFile);
            }
        } catch (Exception var10) {
            result = false;
            this.logger.error("{}", var10.toString());
        } finally {
            fileOut = null;
            outputStream = null;
        }

        return result;
    }

    @Override
    protected boolean deleteFileSub(String strRemoteFile) {
        boolean result = false;

        try {
            if (this.ftpClient != null) {
                result = this.ftpClient.deleteFile(strRemoteFile);
                this.logger.info("工作目录:{},删除文件成功：{}", this.workingDirectory, strRemoteFile);
            }
        } catch (IOException var4) {
            result = false;
            this.logger.error("{}", var4.toString());
        }

        return result;
    }

    private boolean removeAll(String folderDir) {
        try {
            FTPFile[] files = this.ftpClient.listFiles(folderDir);
            FTPFile[] var6 = files;
            int var5 = files.length;

            for (int var4 = 0; var4 < var5; ++var4) {
                FTPFile f = var6[var4];
                if (f.isDirectory() && !StringUtils.equals(".", f.getName()) && !StringUtils.equals("..", f.getName())) {
                    this.removeAll(folderDir + "/" + f.getName());
                    this.ftpClient.removeDirectory(folderDir + "/" + f.getName());
                }

                if (f.isFile()) {
                    this.deleteFileSub(folderDir + "/" + f.getName());
                }
            }

            this.ftpClient.removeDirectory(folderDir);
            return true;
        } catch (IOException var7) {
            this.logger.error("{}", var7.toString());
            return false;
        }
    }

    @Override
    protected boolean removeDirectorySub(String strWorkingDirectory) {
        boolean result = false;

        try {
            result = this.removeAll(strWorkingDirectory);
            this.logger.info("工作目录:{},删除目录成功：{}", this.workingDirectory, strWorkingDirectory);
        } catch (Exception var4) {
            result = false;
            result = this.removeAll(strWorkingDirectory);
            this.logger.error("{}", var4.toString());
        }

        return result;
    }

    @Override
    protected boolean copyFileSub(String strRemoteSourceFile, String strRemoteTargetFile) {
        boolean booResult = false;
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ByteArrayInputStream in = null;

        try {
            if (this.ftpClient != null) {
                String strDir = StringUtils.substringBeforeLast(strRemoteSourceFile, "/");
                this.ftpClient.retrieveFile(strRemoteSourceFile, byteArrayOutputStream);
                in = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
                strDir = StringUtils.substringBeforeLast(strRemoteTargetFile, "/");
                if (StringUtils.isNotBlank(strDir) && !this.changeWorkingDirectorySub(strDir)) {
                    this.createDirectorySub(strDir);
                }

                if (this.checkRemoteFileSub(strRemoteTargetFile)) {
                    String strSuffix = StringUtils.substringAfterLast(strRemoteTargetFile, ".");
                    String strSubNewFileName = (new SimpleDateFormat("_MMddHHmmss")).format(new Date());
                    strRemoteTargetFile = StringUtils.substringBeforeLast(strRemoteTargetFile, ".").replaceAll("_\\d{10,}", "") + strSubNewFileName;
                    if (StringUtils.isNotBlank(strSuffix)) {
                        strRemoteTargetFile = strRemoteTargetFile + "." + strSuffix;
                    }
                }

                booResult = this.ftpClient.storeFile(strRemoteTargetFile, in);
            }
        } catch (Exception var12) {
            booResult = false;
            this.logger.error("{}", var12.toString());
        } finally {
            byteArrayOutputStream = null;
            in = null;
        }

        return booResult;
    }

    @Override
    protected boolean renameSub(String strRemoteOldName, String strRemoteNewName) {
        boolean result = false;

        try {
            if (this.ftpClient != null) {
                result = this.ftpClient.rename(strRemoteOldName, strRemoteNewName);
                this.logger.info("工作目录:{},文件重命名成功：{}", this.workingDirectory, strRemoteNewName);
            }
        } catch (IOException var5) {
            result = false;
            this.logger.error("{}", var5.toString());
        }

        return result;
    }

    @Override
    protected List<String> getFileListSub(String strRemotePath) {
        List<String> ftpFileList = new ArrayList();
        FTPFile[] ftpFileArray = null;

        try {
            if (this.ftpClient.changeWorkingDirectory(strRemotePath)) {
                ftpFileArray = this.ftpClient.listFiles();
                if (ftpFileArray != null && ftpFileArray.length != 0) {
                    this.logger.info("ftpFileArray!=null");
                    FTPFile[] var7 = ftpFileArray;
                    int var6 = ftpFileArray.length;

                    for (int var5 = 0; var5 < var6; ++var5) {
                        FTPFile ftpFile = var7[var5];
                        this.logger.info(ftpFile.getName());
                        if (!".".equals(ftpFile.getName()) && !"..".equals(ftpFile.getName())) {
                            ftpFileList.add(ftpFile.getName());
                        }
                    }
                } else {
                    this.logger.info("目录：{},下面文件夹和文件数目为空", this.workingDirectory);
                }
            }
        } catch (IOException var8) {
            this.logger.error("{}", var8.toString());
        }

        return ftpFileList;
    }

    @Override
    protected boolean changeWorkingDirectorySub(String strWorkingDirectory) {
        boolean result = false;

        try {
            result = this.ftpClient.changeWorkingDirectory(strWorkingDirectory);
            this.logger.info("工作目录:{},跳转目录成功：{}", this.workingDirectory, strWorkingDirectory);
            this.workingDirectory = strWorkingDirectory;
        } catch (IOException var4) {
            result = false;
            this.logger.error("{}", var4.toString());
        }

        return result;
    }

    @Override
    protected boolean createDirectorySub(String strWorkingDirectory) {
        boolean result = false;

        try {
            String[] strArrayPath = StringUtils.split(strWorkingDirectory, "/");
            String root = "/";
            if (this.ftpClient.changeWorkingDirectory(root)) {
                String[] var8 = strArrayPath;
                int var7 = strArrayPath.length;

                for (int var6 = 0; var6 < var7; ++var6) {
                    String strPath = var8[var6];
                    if (StringUtils.isNotBlank(strPath) && !this.ftpClient.changeWorkingDirectory("./" + strPath)) {
                        this.ftpClient.makeDirectory(strPath);
                        result = this.ftpClient.changeWorkingDirectory("./" + strPath);
                    }
                }

                this.logger.info("工作目录:{},创建目录成功：{}", this.workingDirectory, strWorkingDirectory);
                this.workingDirectory = strWorkingDirectory;
            }
        } catch (IOException var9) {
            result = false;
            this.logger.error("{}", var9.toString());
        }

        return result;
    }

    @Override
    protected boolean checkRemoteFileSub(String strRemoteFile) {
        boolean booResult = false;
        FTPFile[] ftpFileArray = null;

        try {
//            strRemoteFile=new String(strRemoteFile.getBytes("GBK"),"UTF-8");
            ftpClient.enterLocalPassiveMode();
            ftpFileArray = this.ftpClient.listFiles(strRemoteFile);

            if (ftpFileArray != null) {
                for (FTPFile f : ftpFileArray) {
                    if (".".equals(f.getName())) {

                    } else if ("..".equals(f.getName())) {

                    } else {
                        booResult = true;
                    }
                }
            }


            if (!booResult) {
                this.logger.info("指定的FTP文件不存在，路径3：{},文件名：{}。", this.workingDirectory, strRemoteFile);

            }


        } catch (Exception var5) {
            this.logger.error("{}", var5.toString());
        }

        return booResult;
    }
}
